import axios, { AxiosError } from 'axios';
import * as vscode from 'vscode';

interface ZhipuAI {
    generateCommitMessage(diff: string, type: string): Promise<string>;
}

interface ZhipuResponse {
    choices: Array<{
        finish_reason: string;
        index: number;
        message: {
            content: string;
            role: string;
        };
    }>;
    created: number;
    id: string;
    model: string;
    request_id: string;
    usage: {
        completion_tokens: number;
        prompt_tokens: number;
        total_tokens: number;
    };
}

interface ZhipuError {
    message: string;
    code?: number | string;
    error?: {
        code: string;
        message: string;
    };
    [key: string]: any;
}

export class ZhipuAIImpl implements ZhipuAI {
    private readonly apiKey = '50acc888fbb254aa3eb88feec4afcb54.mSP4JFHakd0Oddvc';
    private readonly baseUrl = 'https://open.bigmodel.cn/api/paas/v4/chat/completions';
    private readonly maxRetries = 3;
    private readonly retryDelay = 1000; // 1 second

    private getAuthHeaders() {
        return {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.apiKey}`
        };
    }

    private async delay(ms: number): Promise<void> {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    private isRateLimitError(error: any): boolean {
        if (axios.isAxiosError(error)) {
            const axiosError = error as AxiosError<ZhipuError>;
            const errorMessage = axiosError.response?.data?.error?.message || 
                               axiosError.response?.data?.message || 
                               axiosError.message;
            
            return errorMessage?.toLowerCase().includes('rate limit') ||
                   errorMessage?.toLowerCase().includes('resource_exhausted');
        }
        return false;
    }

    async generateCommitMessage(diff: string, type: string): Promise<string> {
        let lastError: Error | null = null;
        
        for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
            try {
                let prompt = '';
                switch (type) {
                    case 'feat':
                        prompt = `分析Git diff内容 关注新增的功能

要求
1 重点关注新添加的代码和功能
2 描述这个新功能的主要作用
3 用一句话描述新增内容 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                        break;
                    case 'fix':
                        prompt = `分析Git diff内容 关注修复的问题

要求
1 重点关注修改和删除的代码
2 描述修复了什么问题
3 用一句话描述修复内容 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                        break;
                    case 'docs':
                        prompt = `分析Git diff内容 关注文档更新

要求
1 重点关注文档和注释的变更
2 描述更新了什么文档内容
3 用一句话描述更新内容 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                        break;
                    case 'style':
                        prompt = `分析Git diff内容 关注代码格式优化

要求
1 重点关注代码格式和结构的变更
2 描述改进了哪些代码风格
3 用一句话描述优化内容 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                        break;
                    case 'refactor':
                        prompt = `分析Git diff内容 关注代码重构

要求
1 重点关注代码结构的改变
2 描述如何优化了代码设计
3 用一句话描述重构内容 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                        break;
                    case 'test':
                        prompt = `分析Git diff内容 关注测试相关更新

要求
1 重点关注测试用例的变更
2 描述添加或修改了什么测试
3 用一句话描述测试内容 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                        break;
                    default:
                        prompt = `分析Git diff内容 提取关键代码改动

要求
1 只关注核心功能代码的变更
2 忽略注释文档等非关键改动
3 用一句话描述关键改动 不超过100字
4 不使用标点符号
5 尽量简短精炼`;
                }

                const requestBody = {
                    model: 'glm-4-flash',
                    messages: [
                        {
                            role: "user",
                            content: `${prompt}

Git diff内容：
${diff}`
                        }
                    ]
                };

                const response = await axios.post<ZhipuResponse>(
                    this.baseUrl,
                    requestBody,
                    {
                        headers: this.getAuthHeaders(),
                        timeout: 30000 // 30 seconds timeout
                    }
                );

                if (!response.data) {
                    throw new Error('API 响应为空');
                }

                if (!response.data.choices?.[0]?.message?.content) {
                    throw new Error('API 响应格式错误: 缺少必要的字段');
                }

                return response.data.choices[0].message.content.trim();

            } catch (error: unknown) {
                lastError = error as Error;

                if (this.isRateLimitError(error)) {
                    if (attempt === this.maxRetries) {
                        throw new Error('已达到 API 速率限制，请稍后再试（约一小时后）');
                    }
                    await this.delay(this.retryDelay * attempt); // 指数退避
                    continue;
                }

                if (axios.isAxiosError(error)) {
                    const axiosError = error as AxiosError<ZhipuError>;
                    if (axiosError.response) {
                        throw new Error(`API 请求失败 (${axiosError.response.status}): ${
                            axiosError.response.data?.error?.message || 
                            axiosError.response.data?.message || 
                            axiosError.message || 
                            '未知错误'
                        }`);
                    } else if (axiosError.request) {
                        throw new Error('无法连接到智普 AI 服务');
                    } else {
                        throw new Error(`请求配置错误: ${axiosError.message}`);
                    }
                }

                throw error;
            }
        }

        throw lastError || new Error('生成提交消息失败');
    }
}

export function getZhipuAI(): ZhipuAI {
    return new ZhipuAIImpl();
}
